/*
 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "adapter/ohos/entrance/ui_event_impl.h"

#include <dlfcn.h>
#include <string>
#include <unordered_map>

#include "interfaces/inner_api/ace/ui_event.h"

#include "base/log/log.h"
#include "base/thread/background_task_executor.h"
#include "core/common/container.h"
#include "core/common/recorder/event_controller.h"
#include "core/common/recorder/event_recorder.h"
#include "core/common/recorder/node_data_cache.h"
#include "core/components_ng/base/inspector.h"

namespace OHOS::Ace {
extern "C" ACE_FORCE_EXPORT void OHOS_ACE_RegisterUIEventObserver(std::string* config, void* observer)
{
    LOGI("Ace lib loaded, RegisterUIEventObserver.");
    Recorder::EventController::Get().Register(config, reinterpret_cast<OHOS::Ace::UIEventObserver*>(observer));
}

extern "C" ACE_FORCE_EXPORT void OHOS_ACE_UnregisterUIEventObserver(void* observer)
{
    LOGI("Ace lib loaded, UnregisterUIEventObserver.");
    Recorder::EventController::Get().Unregister(reinterpret_cast<OHOS::Ace::UIEventObserver*>(observer));
}

extern "C" ACE_FORCE_EXPORT void OHOS_ACE_GetNodeProperty(
    std::string* pageUrl, std::unordered_map<std::string, std::string>* nodeProperties)
{
    LOGD("Ace lib loaded, GetNodeProperty.");
    Recorder::EventController::Get().GetNodeProperty(pageUrl, nodeProperties);
}

extern "C" ACE_FORCE_EXPORT void OHOS_ACE_GetSimplifiedInspectorTree(std::string& tree)
{
    LOGD("Ace lib loaded, GetSimplifiedInspectorTree.");
    auto containerId = Recorder::EventRecorder::Get().GetContainerId();
    auto container = Container::GetContainer(containerId);
    if (!container) {
        return;
    }
    if (container->IsUseNewPipeline()) {
        tree = NG::Inspector::GetSimplifiedInspector(containerId);
    }
}

namespace Recorder {
#if defined (__arm__)
const char HA_CLIENT_SO_PATH[] = "/system/lib/libha_client.z.so";
#else
const char HA_CLIENT_SO_PATH[] = "/system/lib64/libha_client.z.so";
#endif

static void* handle_ = nullptr;

void InitHandler()
{
    if (handle_) {
        return;
    }
    auto handle = dlopen(HA_CLIENT_SO_PATH, RTLD_LAZY);
    if (handle == nullptr) {
        LOGE("Failed to open shared library %{public}s, reason: %{public}sn", HA_CLIENT_SO_PATH, dlerror());
        return;
    }
    handle_ = handle;
}

void Init()
{
    if (NodeDataCache::Get().IsReady()) {
        return;
    }
    BackgroundTaskExecutor::GetInstance().PostTask([]() {
        LOGI("UIEvent report ace loaded");
        InitHandler();
        NodeDataCache::Get().SetReady();
    });
}

void Unit()
{
    if (handle_) {
        dlclose(handle_);
        handle_ = nullptr;
    }
}
} // namespace OHOS::Ace::Recorder
} // namespace OHOS::Ace
